Skip to content

Add hash enrichment from lockfiles to SBOMs#160

Merged
vpetersson merged 10 commits intomasterfrom
add-hash
Jan 31, 2026
Merged

Add hash enrichment from lockfiles to SBOMs#160
vpetersson merged 10 commits intomasterfrom
add-hash

Conversation

@vpetersson
Copy link
Contributor

Extract cryptographic hashes from lockfiles and add them to SBOM components. This addresses the gap where SBOM generators don't capture hashes that exist in lockfiles.

Supported lockfiles:

  • Python: uv.lock, Pipfile.lock, poetry.lock
  • Rust: Cargo.lock
  • Dart: pubspec.lock
  • JavaScript: package-lock.json, yarn.lock, pnpm-lock.yaml

Key features:

  • One hash per package (prefers wheel over sdist, universal over platform-specific)
  • Deduplicates by (name, version) across nested dependencies
  • Feature parity between CycloneDX and SPDX formats
  • Audit trail integration for compliance tracking
  • Non-fatal errors (warns but continues pipeline)

vpetersson and others added 10 commits January 31, 2026 10:13
This refactors the enrichment module to set the supplier field to the
distribution platform (PyPI, npm, crates.io, etc.) rather than the
package author/maintainer. This better reflects NTIA semantics where
"supplier" means the entity distributing the software.

Changes:
- Add PURL_TYPE_TO_SUPPLIER mapping in purl.py with 17 platform entries
- Add get_supplier_for_purl() helper for unified supplier resolution
- Update all enrichment sources to use centralized mapping:
  - pypi.py: "Python Package Index (PyPI)"
  - cratesio.py: "crates.io"
  - pubdev.py: "pub.dev"
  - conan.py: "Conan Center"
  - depsdev.py: Uses mapping based on PURL type
  - ecosystems.py: Uses mapping based on PURL type
- Author info preserved in maintainer_name field (maps to SPDX originator)
- Update tests to reflect new supplier behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test assertions to expect distribution platform as supplier:
- test_pypi_author_email_without_author: expects "Python Package Index (PyPI)"
- test_ecosystems_uses_platform_as_supplier: renamed from test_ecosystems_does_not_use_platform_as_supplier

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests that mock the sbomify API were being affected by the local
sbomify.json file loaded by the JsonConfigProvider. Add patches to
disable the JsonConfigProvider in these tests to ensure proper isolation.

Affected tests:
- test_augmentation_module.py: 6 tests
- test_container_sbom_ntia_compliance.py: 1 test
- test_schema_compliance.py: 2 tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CycloneDX components now have both publisher and supplier fields:
- publisher = package author/maintainer (e.g., "Django Software Foundation")
- supplier = distribution platform (e.g., "Python Package Index (PyPI)")

This addresses sbomqs comp_with_supplier compliance requirement.

Changes:
- Import OrganizationalEntity for CycloneDX supplier field
- Set component.supplier to distribution platform from NormalizedMetadata
- For OS packages (deb/rpm/apk), set maintainer_name = supplier so publisher
  shows the distribution name (e.g., "Debian Project")
- Update tests for correct publisher/supplier expectations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract cryptographic hashes from lockfiles and add them to SBOM
components. This addresses the gap where SBOM generators don't
capture hashes that exist in lockfiles.

Supported lockfiles:
- Python: uv.lock, Pipfile.lock, poetry.lock
- Rust: Cargo.lock
- Dart: pubspec.lock
- JavaScript: package-lock.json, yarn.lock, pnpm-lock.yaml

Key features:
- One hash per package (prefers wheel over sdist, universal over platform-specific)
- Deduplicates by (name, version) across nested dependencies
- Feature parity between CycloneDX and SPDX formats
- Audit trail integration for compliance tracking
- Non-fatal errors (warns but continues pipeline)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The hash enrichment parsers use tomllib which is only available in
Python 3.11+. Updated requirements and CI workflow accordingly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vpetersson vpetersson merged commit 82e8146 into master Jan 31, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant